
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.

import NECommonKit
import NIMSDK
import UIKit

@objcMembers
open class ChatMessageFileCell: NormalChatMessageBaseCell {
    weak var weakModel: MessageFileModel?
    
    public lazy var imgViewLeft: UIImageView = {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = .clear
        imageView.accessibilityIdentifier = "id.fileType"
        return imageView
    }()
    
    public lazy var stateViewLeft: FileStateView = {
        let stateView = FileStateView()
        stateView.translatesAutoresizingMaskIntoConstraints = false
        stateView.backgroundColor = .clear
        stateView.accessibilityIdentifier = "id.fileStatus"
        return stateView
    }()
    
    public lazy var titleLabelLeft: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.isUserInteractionEnabled = false
        label.numberOfLines = 2
        label.lineBreakMode = .byTruncatingMiddle
        label.font = messageTextFont
        label.textAlignment = .left
        label.accessibilityIdentifier = "id.displayName"
        return label
    }()
    
    public lazy var sizeLabelLeft: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textColor = UIColor(hexString: "#999999")
        label.font = NEConstant.defaultTextFont(10.0)
        label.textAlignment = .left
        label.accessibilityIdentifier = "id.displaySize"
        return label
    }()
    
    public lazy var labelViewLeft: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.isUserInteractionEnabled = false
        view.addSubview(titleLabelLeft)
        NSLayoutConstraint.activate([
            titleLabelLeft.leftAnchor.constraint(equalTo: view.leftAnchor),
            titleLabelLeft.topAnchor.constraint(equalTo: view.topAnchor),
            titleLabelLeft.rightAnchor.constraint(equalTo: view.rightAnchor),
            titleLabelLeft.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        ])
        
        sizeLabelLeft.isHidden = true
        view.addSubview(sizeLabelLeft)
        NSLayoutConstraint.activate([
            sizeLabelLeft.leftAnchor.constraint(equalTo: view.leftAnchor),
            sizeLabelLeft.topAnchor.constraint(equalTo: titleLabelLeft.bottomAnchor, constant: 5),
            sizeLabelLeft.rightAnchor.constraint(equalTo: view.rightAnchor),
            sizeLabelLeft.heightAnchor.constraint(equalToConstant: 10),
        ])
        return view
    }()
    
    public lazy var imgViewRight: UIImageView = {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = .clear
        imageView.accessibilityIdentifier = "id.fileType"
        return imageView
    }()
    
    public lazy var stateViewRight: FileStateView = {
        let state = FileStateView()
        state.translatesAutoresizingMaskIntoConstraints = false
        state.backgroundColor = .clear
        state.accessibilityIdentifier = "id.fileStatus"
        return state
    }()
    
    public lazy var titleLabelRight: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.isUserInteractionEnabled = false
        label.numberOfLines = 2
        label.lineBreakMode = .byTruncatingMiddle
        label.font = messageTextFont
        label.textAlignment = .left
        label.accessibilityIdentifier = "id.displayName"
        return label
    }()
    
    public lazy var sizeLabelRight: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textColor = UIColor(hexString: "#999999")
        label.font = NEConstant.defaultTextFont(10.0)
        label.textAlignment = .left
        label.accessibilityIdentifier = "id.displaySize"
        return label
    }()
    
    public lazy var labelViewRight: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.isUserInteractionEnabled = false
        view.addSubview(titleLabelRight)
        NSLayoutConstraint.activate([
            titleLabelRight.leftAnchor.constraint(equalTo: view.leftAnchor),
            titleLabelRight.topAnchor.constraint(equalTo: view.topAnchor),
            titleLabelRight.rightAnchor.constraint(equalTo: view.rightAnchor),
            titleLabelRight.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        ])
        
        sizeLabelRight.isHidden = true
        view.addSubview(sizeLabelRight)
        NSLayoutConstraint.activate([
            sizeLabelRight.leftAnchor.constraint(equalTo: view.leftAnchor),
            sizeLabelRight.topAnchor.constraint(equalTo: titleLabelRight.bottomAnchor, constant: 5),
            sizeLabelRight.rightAnchor.constraint(equalTo: view.rightAnchor),
            sizeLabelRight.heightAnchor.constraint(equalToConstant: 10),
        ])
        return view
    }()
    
    override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupUI()
    }
    
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    open func setupUI() {
        setupUIRight()
        setupUILeft()
    }
    
    open func setupUILeft() {
        bubbleImageLeft.backgroundColor = .white
        
        bubbleImageLeft.addSubview(imgViewLeft)
        NSLayoutConstraint.activate([
            imgViewLeft.leftAnchor.constraint(equalTo: bubbleImageLeft.leftAnchor, constant: 15),
            imgViewLeft.centerYAnchor.constraint(equalTo: bubbleImageLeft.centerYAnchor),
            imgViewLeft.widthAnchor.constraint(equalToConstant: 36),
            imgViewLeft.heightAnchor.constraint(equalToConstant: 43),
        ])
        
        imgViewLeft.addSubview(stateViewLeft)
        NSLayoutConstraint.activate([
            stateViewLeft.leftAnchor.constraint(equalTo: imgViewLeft.leftAnchor, constant: 0),
            stateViewLeft.topAnchor.constraint(equalTo: imgViewLeft.topAnchor, constant: 0),
            stateViewLeft.widthAnchor.constraint(equalToConstant: 36),
            stateViewLeft.heightAnchor.constraint(equalToConstant: 43),
        ])
        
        bubbleImageLeft.addSubview(labelViewLeft)
        NSLayoutConstraint.activate([
            labelViewLeft.leftAnchor.constraint(equalTo: imgViewLeft.rightAnchor, constant: 8),
            labelViewLeft.topAnchor.constraint(equalTo: bubbleImageLeft.topAnchor, constant: 15),
            labelViewLeft.rightAnchor.constraint(equalTo: bubbleImageLeft.rightAnchor, constant: -15),
            labelViewLeft.bottomAnchor.constraint(equalTo: bubbleImageLeft.bottomAnchor, constant: -15),
        ])
    }
    
    open func setupUIRight() {
        bubbleImageRight.backgroundColor = .white
        
        bubbleImageRight.addSubview(imgViewRight)
        NSLayoutConstraint.activate([
            imgViewRight.rightAnchor.constraint(equalTo: bubbleImageRight.rightAnchor, constant: -15),
            imgViewRight.centerYAnchor.constraint(equalTo: bubbleImageRight.centerYAnchor),
            imgViewRight.widthAnchor.constraint(equalToConstant: 36),
            imgViewRight.heightAnchor.constraint(equalToConstant: 43),
        ])
        
        imgViewRight.addSubview(stateViewRight)
        NSLayoutConstraint.activate([
            stateViewRight.rightAnchor.constraint(equalTo: imgViewRight.rightAnchor, constant: 0),
            stateViewRight.topAnchor.constraint(equalTo: imgViewRight.topAnchor, constant: 0),
            stateViewRight.widthAnchor.constraint(equalToConstant: 36),
            stateViewRight.heightAnchor.constraint(equalToConstant: 43),
        ])
        
        bubbleImageRight.addSubview(labelViewRight)
        NSLayoutConstraint.activate([
            labelViewRight.leftAnchor.constraint(equalTo: bubbleImageRight.leftAnchor, constant: 15),
            labelViewRight.topAnchor.constraint(equalTo: bubbleImageRight.topAnchor, constant: 15),
            labelViewRight.rightAnchor.constraint(equalTo: imgViewRight.leftAnchor, constant: -8),
            labelViewRight.bottomAnchor.constraint(equalTo: bubbleImageRight.bottomAnchor, constant: -15),
        ])
    }
    
    override open func showLeftOrRight(showRight: Bool) {
        super.showLeftOrRight(showRight: showRight)
        imgViewLeft.isHidden = showRight
        stateViewLeft.isHidden = showRight
        labelViewLeft.isHidden = showRight
        
        imgViewRight.isHidden = !showRight
        stateViewRight.isHidden = !showRight
        labelViewRight.isHidden = !showRight
    }
    
    override open func setModel(_ model: MessageContentModel, _ isSend: Bool) {
        super.setModel(model, isSend)
        let stateView = isSend ? stateViewRight : stateViewLeft
        let imgView = isSend ? imgViewRight : imgViewLeft
        let titleLabel = isSend ? titleLabelRight : titleLabelLeft
        let sizeLabel = isSend ? sizeLabelRight : sizeLabelLeft
        let bubbleW = isSend ? bubbleWRight : bubbleWLeft
        
        bubbleW?.constant = kScreenWidth <= 320 ? 222 : 242 // 适配小屏幕
        
        if let fileObject = model.message?.attachment as? V2NIMMessageFileAttachment {
            if let fileModel = model as? MessageFileModel {
                weakModel?.cell = nil
                weakModel = fileModel
                fileModel.cell = self
                fileModel.size = Float(fileObject.size)
                if fileModel.state == .Success {
                    stateView.state = .FileOpen
                } else {
                    stateView.state = .FileDownload
                    stateView.setProgress(Float(fileModel.progress / 100))
                    if fileModel.progress >= 100 {
                        fileModel.state = .Success
                    }
                }
            }
            var imageName = "icon_file_unknown"
            let suffix = (fileObject.name as NSString).pathExtension.lowercased()
            switch suffix {
            case file_doc_support:
                imageName = "icon_file_word"
            case file_xls_support:
                imageName = "icon_file_excel"
            case file_img_support:
                imageName = "icon_file_unknown"//file_img
            case file_ppt_support:
                imageName = "icon_file_unknown"//file_ppt
            case file_txt_support:
                imageName = "icon_file_txt"
            case file_audio_support:
                imageName = "icon_file_unknown"//file_audio
            case file_vedio_support:
                imageName = "icon_file_unknown"//file_vedio
            case file_zip_support:
                imageName = "icon_file_unknown"//file_zip
            case file_pdf_support:
                imageName = "icon_file_pdf"
            case file_html_support:
                imageName = "icon_file_unknown"//file_html
            case "key", "keynote":
                imageName = "icon_file_unknown"//file_keynote
            default:
                imageName = "icon_file_unknown"
            }
            
            imgView.image = UIImage.ne_imageNamed(name: imageName)
            titleLabel.text = fileObject.name
            
            let size_B = Double(fileObject.size)
            var size_str = String(format: "%.1f B", size_B)
            if size_B > 1e3 {
                let size_KB = size_B / 1e3
                size_str = String(format: "%.1f KB", size_KB)
                if size_KB > 1e3 {
                    let size_MB = size_KB / 1e3
                    size_str = String(format: "%.1f MB", size_MB)
                    if size_MB > 1e3 {
                        let size_GB = size_KB / 1e6
                        size_str = String(format: "%.1f GB", size_GB)
                    }
                }
            }
            sizeLabel.text = size_str
        }
    }
    
    override open func uploadProgress(_ progress: UInt) {
        let stateView = stateViewLeft.isHidden ? stateViewRight : stateViewLeft
        stateView.setProgress(Float(progress) / 100)
    }
}
